﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace Brain
{
#if WINDOWS
    public class WindowsDefaultInputManager : IInputManager
    {
        public KeyboardState LastKeyboardState;
        public KeyboardState KeyboardState;

        public MouseState LastMouseState;
        public MouseState MouseState;

        public GamePadState[] LastGamePadStates;
        public GamePadState[] GamePadStates;

        public bool ShouldUpdate { get; set; }

        public bool EnableMouseAsTouch = false;

        public WindowsDefaultInputManager()
        {
            KeyboardState = Keyboard.GetState();
            LastKeyboardState = KeyboardState;

            MouseState = Mouse.GetState();
            LastMouseState = MouseState;

            GamePadStates = new GamePadState[4];
            LastGamePadStates = new GamePadState[4];
            for (int i = 0; i < 4; i++)
            {
                GamePadStates[i] = GamePad.GetState((PlayerIndex)i);
                LastGamePadStates[i] = GamePadStates[i];
            }

            ShouldUpdate = true;
        }

        #region Exclusive Windows
        
        public bool IsKeyDown(Enum Key)
        {
            return KeyboardState.IsKeyDown((Keys)Key);
        }

        public bool IsKeyUp(Enum Key)
        {
            return KeyboardState.IsKeyUp((Keys)Key);
        }

        public bool IsKeyPress(Enum Key)
        {
            return KeyboardState.IsKeyDown((Keys)Key) &&
                LastKeyboardState.IsKeyUp((Keys)Key);
        }

        #region Mouse

        private Vector2 mouseDifference;
        public Vector2 GetMouseDifference()
        {
            return mouseDifference;
        }

        public void SetMousePosition(int X, int Y)
        {
            Mouse.SetPosition(X, Y);
        }

        public Vector2 GetMousePosition()
        {
            return new Vector2(MouseState.X, MouseState.Y);
        }

        public bool IsMouseLeftDown()
        {
            return MouseState.LeftButton == ButtonState.Pressed;
        }
        public bool IsMouseRightDown()
        {
            return MouseState.RightButton == ButtonState.Pressed;
        }
        public bool IsMouseMiddleDown()
        {
            return MouseState.MiddleButton == ButtonState.Pressed;
        }

        public bool IsMouseLeftUp()
        {
            return MouseState.LeftButton == ButtonState.Released;
        }
        public bool IsMouseRightUp()
        {
            return MouseState.RightButton == ButtonState.Released;
        }
        public bool IsMouseMiddleUp()
        {
            return MouseState.MiddleButton == ButtonState.Released;
        }


        public bool IsMouseLeftClick()
        {
            return MouseState.LeftButton == ButtonState.Pressed &&
                LastMouseState.LeftButton == ButtonState.Released;
        }
        public bool IsMouseRightClick()
        {
            return MouseState.RightButton == ButtonState.Pressed &&
                LastMouseState.RightButton == ButtonState.Released;
        }
        public bool IsMouseMiddleClick()
        {
            return MouseState.MiddleButton == ButtonState.Pressed &&
                LastMouseState.MiddleButton == ButtonState.Released;
        }

        public int GetMouseWheelValue()
        {
            return MouseState.ScrollWheelValue;
        }

        public int GetMouseWheelDifference()
        {
            return this.wheelDifference;
        }

        #endregion

        #endregion


        #region Xbox and Win

        public float GetLeftTrigger(PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].Triggers.Left;
        }

        public float GetRightTrigger(PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].Triggers.Right;
        }

        public Vector2 GetLeftThumbstick(PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].ThumbSticks.Left;
        }

        public Vector2 GetRightThumbstick(PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].ThumbSticks.Right;
        }

        public bool IsButtonDown(Enum Button, PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].IsButtonDown((Buttons)Button);
        }

        public bool IsButtonUp(Enum Button, PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].IsButtonUp((Buttons)Button);
        }

        public bool IsButtonPress(Enum Button, PlayerIndex PlayerIndex)
        {
            return GamePadStates[(int)PlayerIndex].IsButtonDown((Buttons)Button) &&
                LastGamePadStates[(int)PlayerIndex].IsButtonUp((Buttons)Button);
        }

        public bool IsAnyPlayerButtonDown(Enum Button)
        {
            for (int i = 0; i < 4; i++)
            {
                if (IsButtonDown(Button, (PlayerIndex)i))
                {
                    return true;
                }
            }
            return false;
        }

        public bool IsAnyPlayerButtonUp(Enum Button)
        {
            for (int i = 0; i < 4; i++)
            {
                if (IsButtonUp(Button, (PlayerIndex)i))
                {
                    return true;
                }
            }
            return false;
        }

        public bool IsAnyPlayerButtonPress(Enum Button)
        {
            for (int i = 0; i < 4; i++)
            {
                if (IsButtonPress(Button, (PlayerIndex)i))
                {
                    return true;
                }
            }
            return false;
        }

        #endregion


        #region Windows Phone

        public Vector2[] GetTouchLocations()
        {
            if (EnableMouseAsTouch)
            {
                return new Vector2[] { GetMousePosition() };
            }
            else
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        public void Reset()
        {
            KeyboardState = Keyboard.GetState();
            LastKeyboardState = KeyboardState;
            
            MouseState = Mouse.GetState();
            LastMouseState = MouseState;

            GamePadStates = new GamePadState[4];
            LastGamePadStates = new GamePadState[4];
            for (int i = 0; i < 4; i++)
            {
                GamePadStates[i] = GamePad.GetState((PlayerIndex)i);
                LastGamePadStates[i] = GamePadStates[i];
            }

            ShouldUpdate = true;
        }


        private int wheelDifference;
        public void Update()
        {
            LastKeyboardState = KeyboardState;
            KeyboardState = Keyboard.GetState();

            LastMouseState = MouseState;
            MouseState = Mouse.GetState();
            mouseDifference = new Vector2(MouseState.X - LastMouseState.X, MouseState.Y - LastMouseState.Y);
            wheelDifference = MouseState.ScrollWheelValue - LastMouseState.ScrollWheelValue;

            for (int i = 0; i < 4; i++)
            {
                LastGamePadStates[i] = GamePadStates[i];
                GamePadStates[i] = GamePad.GetState((PlayerIndex)i);
            }
        }

        public SerializationData Data { get; set; }

        public void SerializeData(DefaultSerializationManager manager)
        {
        }

        public void DeserializeData(DefaultSerializationManager manager, SerializationData newData)
        {
        }












    }
#endif
}
